import React, {
  useEffect,
  useState
} from 'react';
import './style/index.less';
import { ButtonProps } from './interface';
import classNames from 'classnames';

type Loading = number | boolean;

const Button: React.FC<ButtonProps> = (props) => {
  const {
    children,
    block = false,
    icon,
    style,
    noStyle,
    useClass,
    prefixCls = 'dt-btn',
    className,
    type: customType = 'default',
    size = 'middle',
    shape = 'default',
    status = 'default',
    ghost = false,
    htmlType = 'button',
    loading = false,
    disabled = false,
    href,
    target,
    onClick
  } = props;
  const [innerLoading, setInnerLoading] = useState<Loading>(Boolean(loading));
  const [animating, setAnimating] = useState<boolean>(false);

  const handleAnimating = (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
    if (customType !== 'link' && customType !== 'text') {
      const current = e.currentTarget;
      const getAnimating = current.getAttribute('dt-btn-click-animating');
      if (!getAnimating) {
        current.setAttribute('dt-btn-click-animating', 'false');
      }

      if (!animating) {
        setAnimating(true);
        current.setAttribute('dt-btn-click-animating', 'true');
        setTimeout(() => {
          setAnimating(false);
          current.setAttribute('dt-btn-click-animating', 'false');
        }, 360);
      }
    }
  };

  const handleOnClick = (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
    if (disabled || innerLoading) {
      e.preventDefault();
      return;
    }
    onClick?.(e);
    handleAnimating(e);
  };

  const loadingOrDelay: Loading = typeof loading === 'boolean' ? loading : loading?.delay || true;

  useEffect(() => {
    let delayTimer: number | null = null;

    if (typeof loadingOrDelay === 'number') {
      delayTimer = window.setTimeout(() => {
        delayTimer = null;
        setInnerLoading(loadingOrDelay);
      }, loadingOrDelay);
    } else {
      setInnerLoading(loadingOrDelay);
    }

    return () => {
      if (delayTimer) {
        window.clearTimeout(delayTimer);
        delayTimer = null;
      }
    };
  }, [loadingOrDelay]);

  const buttonCls = noStyle ? useClass : classNames(
    `${prefixCls}`,
    {
      [`${prefixCls}-${customType}`]: customType,
      [`${prefixCls}-${size}`]: size !== 'middle',
      [`${prefixCls}-${shape}`]: shape !== 'default' && shape,
      [`${prefixCls}-${status}`]: status !== 'default',
      [`${prefixCls}-disabled`]: disabled,
      [`${prefixCls}-background-ghost`]: ghost,
      [`${prefixCls}-loading`]: innerLoading,
      [`${prefixCls}-only-icon`]: !children && icon,
      [`${prefixCls}-block`]: block
    },
    className
  );

  const iconRender = (src: React.ReactNode | string) => {
    if (typeof src === 'string') {
      return <img src={src} className={`${prefixCls}-icon-${icon?.position || 'left'}`} />;
    }
    return <span className={`${prefixCls}-icon-${icon?.position || 'left'}`}>{src}</span>;
  };

  const renderNode = () => {
    let iconNode: React.ReactNode = null;
    if (innerLoading) {
      // loading状态时渲染loading图标
      iconNode = (
        <span className={`${prefixCls}-loading-icon`}>
          <span className={`${prefixCls}-icon-${size}`} />
          <span className={`${prefixCls}-icon-${size}`} />
        </span>
      );
    } else {
      // 否则渲染icon图标，无图标时渲染为null
      const iconSrc: React.ReactNode | string = icon?.src;
      iconNode = iconSrc ? iconRender(iconSrc) : null;
    }

    return children && icon && icon.position === 'right' ? (
      <>
        <span>{children}</span>
        {iconNode}
      </>
    ) : (
      <>
        {iconNode}
        <span>{children}</span>
      </>
    );
  };

  const childRender = () => {
    if (!(children || icon)) {
      return null;
    }
    if (href) {
      return (
        <a
          className={buttonCls}
          style={style}
          type={htmlType}
          onClick={handleOnClick}
          href={href}
          target={target}
        // data-dt-btn-click-animating={animating}
        >
          {renderNode()}
        </a>
      );
    }
    return (
      <button
        className={buttonCls}
        style={style}
        type={htmlType}
        onClick={handleOnClick}
        disabled={disabled}
      // data-dt-btn-click-animating={animating}
      >
        {renderNode()}
      </button>
    );
  };

  return (
    childRender()
  );
};
export default Button;
